const {MongoClient,ObjectId, ObjectID} = require('mongodb');
const url = "mongodb://localhost:27017";
const dbName = 'gzh52003';

// 数据库配置
async function connect(){
    const client = await MongoClient.connect(url,{useUnifiedTopology: true });
    const db = client.db(dbName);
    return {client,db}
}

// 一、查
async function find(collectionName,query={},options={}){

    // 1.连接数据库
    const {client,db} = await connect();
    // 2.获取指定集合
    const collection = db.collection(collectionName);

    if(query._id&&typeof query._id==="string"){
        query._id = ObjectId(query._id);
    }

    /* 8.过滤字段，不想传递到前端的数据可以在这里设置 */
    const opt = {}
    if(options.field){
        opt.projection = options.field;
    }
    
    // 3.获取查询结果
    // 注意不要用const定死，否则会报错，因为后面还要变化
    let result = await collection.find(query,opt);  
    // 4.跳过条数
    if(options.skip){
        result = result.skip(options.skip);
    }
    // // 5.限制数量
    if(options.limit){
        result = result.limit(options.limit);
    }
    // 6.排序
    if(options.sort){
        let key,value;
        key = options.sort[0];
        // 若长度大于1，则说明有设置升降序；若没有，则默认降序
        if(options.sort.length>1){
            value = options.sort[1]*1;  // 注意转数字，原先为字符串
        }else{
            value = -1;
        }
        result = result.sort({[key]:value})
    }
    // 7.结果数组化、关闭连接、返回结果
    result = await result.toArray();    // bson格式强制转化为数组格式
    client.close();
    return result;
}

// 二、增
async function insert(collectionName,query={}){
    // 1.连接数据库
    const {db,client} = await connect();
    // 2.获取指定集合
    const collection = db.collection(collectionName);
    // 3.数据库操作
    const result = await collection[Array.isArray(query)?'insertMany':'insertOne'](query);

    // insert可以插一条也可以插多条，但会报警告不推荐使用
    // const result = await collection.insert(query);

    // 关闭连接并返回结果
    client.close();
    return result;
}

// 三、删
async function remove(collectionName,query){

    // 1.连接数据库
    const {db,client} = await connect();
    // 2.获取指定集合
    const collection = db.collection(collectionName);

    // 当传过来的是mongo数据的id时，需要进行特殊转换
    if(query._id&&typeof query._id==="string"){
        query._id = ObjectId(query._id);
    }

    // 3.执行sql语句
    const result = await collection.deleteOne(query)
    // 4.关闭数据库并返回结果
    client.close();
    return result;
}

// 四、改
async function update(collectionName,query,newData){
    // 1.连接数据库
    const {db,client} = await connect();
    // 2.获取指定集合
    const collection = db.collection(collectionName);
    // 处理id
    if(query._id&&typeof query._id === "string"){
        query._id = ObjectId(query._id);
    }
    // 3.获取指定数据并修改
    let result = await collection.updateMany(query,newData);
    // 4.关闭数据库并返回结果
    client.close();
    return result;
}

module.exports = {
    find,
    insert,
    remove,
    update
}